#include <stdio.h>
#include <wait.h>
#include <sys/types.h>
#define	m	1 //Como m é constante, ele somente sera impresso no primeiro fprintf.
int i, j, id, d1, d2, status, filhos[m+1];

void imprimeFilhos(int filhos[m+1], int pidPai){
	fprintf(stdout, "Pids dos filhos de %d: ", pidPai);
	int v;
	for(v = 0; v <= m; v++){
		if (filhos[v]) fprintf(stdout, "%d",filhos[v]);
		if ((v != m) && (filhos[v])) fprintf(stdout, ", ",filhos[v]);
		else if (v == m)fprintf(stdout, ".\n",filhos[v]);
	}
}


int main(void) {

	d1 = 1;
	d2 = 2;

	fprintf(stdout,"Valores iniciais: d1 = %d, d2 = %d, m = %d.\n",d1, d2, m); // Imprimindo valores iniciais.
	fprintf(stdout,"Processo Corrente numero %d.\n",getpid()); // Imprimindo o PID.

	//
	//Quais processos executarao este trecho do codigo? Somente o primeiro processo criado.
	//

	j = 0;

	for (i = 0; i <= m; i++) {
		fprintf(stdout,"Processo Corrente numero = %d, i = %d, d1 = %d, d2 = %d.\n", getpid(), i, d1, d2);// Imprimindo o PID, i, d1 e d2.

		//
		// Quais processos executam este trecho do codigo? Somente os processos que nao sao folhas
		// (sao processos pai de algum outro processo) na arvore genealogica de processos criada.
		//

		id = fork();
		filhos[i] = id;

		if (id) {
			d1 = d1 + (i + 1);
			d2 = d2 + d1 * 3;

			fprintf(stdout,"Processo Corrente numero = %d, i = %d, d1 = %d, d2 = %d, ramo THEN do IF 1.\n", getpid(), i, d1, d2);// Imprimindo o PID, i, d1 e d2, ramo THEN.

			//
			// Quais processos executam este trecho do codigo? Somente os processos que nao sao folhas
			// (sao processos pai de algum outro processo) na arvore genealogica de processos criada.
			//

		} else {
			d1 = d1 + (i + 1) + 5;
			d2 = d2 + d1 * 3 + 5;
			j = i + 1;

			fprintf(stdout,"Processo Corrente numero = %d, i = %d, d1 = %d, d2 = %d, ramo ELSE do IF 1.\n", getpid(), i, d1, d2);// Imprimindo o PID, i, d1 e d2, ramo ELSE.

			//
			// Quais processos executam este trecho do codigo? Todos os processos menos o primeiro
			// processo criado. (Isso acontece pois todos os processos (menos o primeiro) que tem
			// algum pai entram no else.)
			//

		}
	}

	//
	// Quais processos executam este trecho do codigo? Todos os processos passam por aqui.
	//

	if (id != 0) {
		fprintf(stdout, "Processo Corrente numero = %d, entrou no IF 2 (id != 0).\n", getpid()); // Imprimindo o PID, entrou no IF 2 (id != 0).

		//
		// Quais processos executam este trecho do codigo? Somente os processos que nao sao folhas
		// (sao processos pai de algum outro processo) na arvore genealogica de processos criada.
		// É aqui no for abaixo que os processos pais irao esperar seus filhos para prosseguirem.
		//

		for(i = j; i <= m; i++) {

			//
			// O comando for() foi ajustado de "for(i = j; i == m; i++)" para "for(i = j; i <= m; i++)".
			// Assim modificado, a diferenca "m - (j+1)", ou seja, quantas vezes o for rodar, sera o numero
			// de processos filho que o processo pai ira esperar para continuar o processo apos o for. Cada
			// iteracao do for significa que o processo pai acabou de esperar um dos processos filho.
			// A distancia de j ate m(inclusive, inclusive), entao, é o numero de processos filhos que o processo
			// que esta sendo executado tem.
			//
			// Quais processos executam este trecho do codigo? Somente os processos que nao sao folhas
			// (sao processos pai de algum outro processo) na arvore genealogica de processos criada.
			//

			fprintf(stdout, "Processo Corrente numero = %d, ramo FOR do IF 2 (id != 0), numero de filhos que o processo aguardou: %d/%d.\n", getpid(), i-j,m-j+1 );// Ramo FOR, mostra numeros de filhos que ele aguardou/esta aguardando.
			imprimeFilhos(filhos, getpid()); // Imprime filhos do processo ativo.

			wait(&status);

			if(status == 0) {

				//
				// Como os processos sao sempre terminados com exit(0), o byte da direita de status vale 0,
				// e o byte da esquerda é o parametro passado a exit pelo filho, tambem 0.
				// Quais processos executam este trecho do codigo? Somente os processos que nao sao folhas
				// (sao processos pai de algum outro processo) na arvore genealogica de processos criada.
				//

				fprintf(stdout,"Status == 0, Processo Corrente numero = %d, i = %d, d1 = %d, d2 = %d.\n", getpid(), i, d1, d2);

			} else {

				//
				// Quais processos executam este trecho do codigo? Como citado acima, o status sempre
				// sera igual a 0, entao nao passara nenhum processo por aqui.
				//

				fprintf(stdout,"Status != 0, Processo Corrente numero = %d, i = %d, d1 = %d, d2 = %d.\n", getpid(), i, d1, d2);

			}
		}
	}

	exit(0);
	return 0;
}
